<template>
    <div class="input">
        <el-select v-model="searchKey" filterable clearable remote placeholder="输入姓名搜索"
            :remote-method="remoteMethod" :loading="searchloading"  @change="searchChange"  @clear="clearSearchKey">
            <el-option v-for="item in searchOptions" :key="item.value" :label="item.label"
            :value="item.value" />
        </el-select>

        <!-- 添加按钮 -->
        <el-button type="primary" v-has:add="permissions" :icon="Plus" @click="addStu">
            添加项目
        </el-button>
    </div>
    <div class="export">
        <el-button  @click="exportExcel">
            <template #icon>
                <svg>
                    <use class="icon" xlink:href="#icon-excel"></use>
                </svg>
            </template>
            <template #default>
                导出Excel
            </template>
        </el-button>
    </div>
    <!-- 展示数据的表格 -->
    <div class="table">
        <el-table :data="tableData" border style="width: 100%" :loading="tableloading">
            <el-table-column prop="" label="头像" width="120" align="center">
                <template v-slot="{row}">
                    <div class="block">
                        <el-avatar shape="square" :size="50" :src="row.headimgurl"/>
                    </div>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="150" align="center"/>
            <el-table-column prop="degree" label="学历" width="180" align="center"/>
            <el-table-column prop="class" label="班级" width="180" align="center"/>
            <el-table-column prop="productUrl" label="项目" width="180" align="center"/>
            <el-table-column prop="cTime" label="创建时间" align="center"/>
            <el-table-column label="操作" align="center">
                <template v-slot="{row}">
                    <el-button type="primary" v-has:read="permissions" :icon="View" @click="readStu(row)">
                        查看
                    </el-button>
                    <el-button type="primary" v-has:edit="permissions" :icon="EditPen" @click="updateStu(row)">
                        编辑
                    </el-button>
                    <el-button type="danger" v-has:delete="permissions" :icon="Delete" @click="deleteStu(row)">
                        删除
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
    </div>
    <!-- 分页 -->
    <el-pagination background layout="prev, pager, next " :total="total"
    :current-page="currentPage" @current-change="pageChange" :page-size="pageSizes"/>
    
    <!-- 弹窗组件 -->
    <qf-dialog 
    :visible="dialogVisible"
    :title="dialogTitle"
    @closed="close"
    :dialogFormData="dialogFormData" 
    @validateSuccess="dialogValidateSuccess"
    @dialogCancel="dialogCancel">
        <template v-slot:upload>
            <!-- <el-upload
                v-loading="uploadLoading"
                class="avatar-uploader"
                method="post"
                action="/api/students/uploadStuAvatar"
                name="headimgurl"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload">
                <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload> -->
            <el-upload
                v-loading="uploadLoading"
                class="avatar-uploader"
                method="post"
                action="/api/students/uploadStuAvatar"
                name="headimgurl"
                list-type="picture-card"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload">
                <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
        </template>
    </qf-dialog>
</template>

<script setup>
import {onMounted, ref,reactive} from "vue"
import * as api from "@/api/students.js"
// 引入图标
import {View,EditPen,Delete,Plus} from "@element-plus/icons-vue"
// 引入弹框组件
import qfDialog from "@/components/dialog/index.vue"
// 引入消息提示
import { ElMessage ,ElMessageBox} from 'element-plus'
// 引入路由
import {useRouter} from "vue-router"
// 引入用户store
import {useUser} from "@/store/users.js"
// 引入导出Excel的插件
import qee from "qf-export-excel"
import { get } from "@vueuse/shared"
// 使用用户store
let userStore = useUser()
// 使用路由
let router = useRouter()



// 表格要渲染的数据
let tableData = ref([])
// 表格加载动画
let tableloading = ref(true)


// 搜索的数据
let searchOptions = ref([])
// 搜索框关键字
let searchKey = ref("")
// 搜索动画
let searchloading = ref(false)
// 搜索方法,这里负责呈现搜索的联想数据
let remoteMethod = async (currentKeyword) => {
    if(!currentKeyword){
        return 
    }
    // 开启搜索的动画
    searchloading.value = true
    // 目的是为了保证用户在输入或者选择的时候，搜能获取到搜索关键字
    // let key = searchKey.value ? searchKey.value : currentKeyword
    // console.log(key)
    try{
        // 发起搜索请求
        let res = await api.searchStuListApi(currentKeyword,'')
        // console.log(res)
        // 给联想的列表进行赋值
        let repeatDatas = res.data.data.map(item => ({value:item.name}))
        // console.log(repeatDatas)
        // 去重操作
        let norepeatDatas = []
        // for(var i =0;i<repeatDatas.length;i++){
        //     let flag = true;
        //     for(var j = 0;j<norepeatDatas.length;j++){
        //         if(repeatDatas[i].value ===norepeatDatas[j].value){
        //             flag = false;
        //             break;
        //         }
        //         if(flag){
        //             norepeatDatas.unshift(repeatDatas[i])
        //         }
        //     }
        // }
        repeatDatas.forEach(item => {
            // console.log(item.value)
            
            norepeatDatas.unshift(item.value)
        })
        // console.log(norepeatDatas)
        let newarr = new Set(norepeatDatas)
        let arr1 = [...newarr]
        let arr2 = []
        arr1.forEach(item =>{
            let obj = {
                value:item
            }
            arr2.push(obj)
        })
        // console.log(arr2)
        // 去重之后对option进行去重操作
        searchOptions.value = arr2
        // 关闭搜索的动画
        searchloading.value = false
    }catch(e){
        console.log(e)
        // 关闭搜索的动画
        searchloading.value = false
    }

} 

// 清空关键字之后的方法
let clearSearchKey = () => {
    // 初始化数据，让页码回到第一页
    currentPage.value = 1
}


// 用户选择了输入的值之后再触发，负责更新表格数据
let searchChange = async (key,page=1,count=10) =>{
    // 开启表格的动画
    tableloading.value = true
    // 获取用户点选的值
    // console.log(searchKey.value)
    // 清空上次获取到的选项
    searchOptions.value = []
    try{
        let res = await api.searchStuListApi(searchKey.value,count,page)
        // 给表格数据赋值为搜索结果
        tableData.value = res.data.data
        // 关闭表格的动画
        tableloading.value = false
        // 对搜索的结果进行分页
        setPageNation(res.data.total)
    }catch(e){
        console.log(e)
        // 关闭的表格的动画
        tableloading.value = false
    }
}


// 用户权限
let permissions = ref([])
permissions.value = JSON.parse(sessionStorage.getItem('permission'))

// 局部自定义指令
const vHas = {
    // vue3中自定义指令的钩子函数
    mounted(el,binding){
        //按钮需要的权限edit,从指令参数湖区
        let role = binding.arg;
        //用户权限 [read,add] 从表达式里面获取
        let userRole = binding.value;
        //判断用户有没有按钮的权限
        let hasRole = userRole.includes(role);
        if (!hasRole) {
            //移除
            el.parentNode.removeChild(el)
        }
    }
}


// 调用请求数据方法
onMounted(async ()=>{
    getStuList()
})


// 封装一个方法，专门用于获取表格数据
let getStuList = async (page,count,classes) => {
    try{
        // 发起获取学员列表的请求
        let res = await api.getstuList(page,count,classes)
        
        // 给循环table数据赋值
        tableData.value = res.data.data
        // 关闭加载动画
        tableloading.value = false
        // 设置分页器的数量
        setPageNation(res.data.total)
    }catch(e){
        console.log(e)
        // 关闭加载动画
        tableloading.value = false
    }
    
}



// 处理分页
let total = ref(1)
// 一页展示几条数据
let pageSizes = ref(10)
// 默认的页码
let currentPage = ref(1)
// 页码变更的时候
let pageChange = (inputcurrentPage) =>{
    // 动态变更页码
    currentPage.value = inputcurrentPage
    // 判断有没有搜索关键字，如果有应该更新搜索的分页结果
    if(searchKey.value){
        searchChange(null,inputcurrentPage)
    }else{
        // 拉取全部数据
        getStuList(inputcurrentPage)
    }
    
}

// 专门修改分页内容的方法
let setPageNation = (totalCount=10,pageSize=10,currentPage=1) => {
    total.value = totalCount
    pageSizes.value = pageSize
}





// dialog的数据源,规范dialog数据
let dialogFormData = reactive({
    class:{
        label:'班级',
        value:""
    },	    
    name:{
        label:'姓名',
        value:""
    },	    
    age:{
        label:'年龄',
        value:""
    },    
    city:{
        label:'城市',
        value:""
    },  
    degree:{
        label:'学历',
        value:""
    },	    
    productUrl:{
        label:'项目地址',
        value:""
    },	    
    description:{
        label:'描述',
        value:""
    },	    
})

// dialog标题
let dialogTitle = ref('增加学员信息')


// 上传头像
// 一个保存上传文件的地址的变量
let imageUrl = ref()
// 声明一个headimgurl变量，用于将参数在表单dialog通过的时候，一并提交给后台
let headimgurl = ref("")
// 加载动画
let uploadLoading = ref(false)
// 上传文件---上传成功
let handleAvatarSuccess = (res,uploadFile) => {
    if(res.state){
        // 头像上传成功
        ElMessage({
            type:"success",
            message:res.msg
        })
        headimgurl.value = res.headimgurl
    }else{
        ElMessage({
            type:'error',
            message:res.msg
        })
    }
    // console.log(res)
    // console.log(uploadFile.raw)
    // 关闭加载动画
    uploadLoading.value = false
    imageUrl.value = URL.createObjectURL(uploadFile.raw)
}

// 上传文件---上传之前 
let beforeAvatarUpload = (rawFile) => {
    console.log(rawFile.type)
    // 允许上传的文件类型
    let acceptType = ['image/jpeg','image/png']
    // 判断当前上传的文件类型，是否包含在上面的数组中
    let isAccept = acceptType.includes(rawFile.type)

    // 限制上传大小
    if (!isAccept) {
        ElMessage.error('上传的文件只能是JPEG或者是png，您当前上传的文件类型是'+rawFile.type)
        return false
    } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('上传文件的大小不能超过1MB!')
        return false
    }
    // 打开加载动画
    uploadLoading.value = true
    return true
}

// dialog点击了确定按钮，并且表单校验通触发的逻辑
let dialogValidateSuccess = async (form) => {
    console.log(dialogFormData)
    let message = '添加成功'
    // 发起请求，将输入的内容传递给服务器
    // 传递的参数
    let params = {
        headimgurl:"",
        class:dialogFormData.class.value,
        name:dialogFormData.name.value,
        age:dialogFormData.age.value,
        city:dialogFormData.city.value,
        degree:dialogFormData.degree.value,
        productUrl:dialogFormData.productUrl.value,
        description:dialogFormData.description.value
    }
    try{
        let apiMethod = null
        // 根据dialog来区分要发送编辑请求还是添加请求
        switch(dialogTitle.value){
            case '增加学员信息':
                apiMethod = api.addStuApi
                // 删除sId这条属性
                params.sId ? delete params.sId : ""
                break;
            case '编辑学员信息':
                apiMethod = api.updateStuApi
                // 给params添加sId属性
                params.sId = sId.value
                message  = '修改成功'
        }
        // 判断是否上传头像，如果上传了就携带到params中取
        params.headimgurl = headimgurl.value ? headimgurl.value : ""
        // 发起请求
        let res = await apiMethod(params)
        console.log(res)
        // 1、提示添加成功
        ElMessage({
          message: message,
          type: 'success',
        })
        // 2、关闭dialog
        dialogVisible.value = false
        // 3、清空dialog
        form.value.resetFields()
        console.log('3333333333')
        // 4、更新列表
        if(dialogTitle.value === '增加学员信息'){
            getStuList()
        }else{
            getStuList(currentPage.value)
        }
        // console.log(res)
    }catch(e){
        // console.log(e)
        ElMessage({
          message: e.toString(),
          type: 'error',
        })
    }
    
}

// dialog点击了取消按钮
let dialogCancel = () => {
    console.log('已取消')
    dialogVisible.value = false
    
}

// dialog关闭之后，要同步控制关闭属性的值
// 这么做的目的是为了处理点击空白区域或者右上角叉叉的时候，造成的后续对话框不能弹出的情况
let close =() => {
    dialogVisible.value = false
    // 将数据清空
    let keys = Object.keys(dialogFormData)
    keys.forEach(key => {
        dialogFormData[key].value = ''
    })
    // 清空头像
    imageUrl.value = ''
}

// 添加学员
// 声明dialogVisible控制dialog
let dialogVisible = ref(false)
let addStu = () => {
    dialogVisible.value = true
    // 修改dialogTitle的值
    dialogTitle.value = '增加学员信息'
}

// 编辑学员
// 声明一个sId便于编辑的时候传递给后端
let sId = ref("")
let updateStu = (row) =>{
    console.log(row)
    // 1、打开dialog
    dialogVisible.value = true
    // 修改标题
    dialogTitle.value = '编辑学员信息'
    // 2、数据回写
    let keys = Object.keys(dialogFormData)
    keys.forEach(key => {
        dialogFormData[key].value = row[key]
    })
    // 给sId赋值
    sId.value = row.sId
    // 更改全局的headimgurl这个字段，便于数据的传递
    headimgurl.value = row.headimgurl
    // 数据回写
    imageUrl.value = row.headimgurl

}

// 删除学员
let deleteStu = async (row) => {
    // 消息提示框
        ElMessageBox.confirm('此操作将永久删除'+row.name +'这条数据，是否继续?','删除提示',
        {
            confirmButtonText:'确定',
            cancelButtonText:'取消',
            type:'warning'
        })
        // 点击确定按钮
        .then(async ()=>{
            try{
                // 发起请求，删除数据
                let res = await api.deleteStuApi(row.sId)
                console.log(row.sId)
                // 更新列表
                getStuList(currentPage.value)
                ElMessage({
                    message: '删除成功·',
                    type: 'success',
                })
            }catch(e){
                ElMessage({
                    message: e,
                    type: 'error',
                })
            }
        })
        // 点击取消按钮
        .catch(()=>{
            ElMessage({
                message: '已取消删除',
                type: 'warning',
            })
        })
    

}

// 查看学员
let readStu = (row) => {
    router.push('/studentManager/stuProfile')
    userStore.stuProfile = row
}


// 导出Excel
let exportExcel = () => {
    // 定义表头
    let titleSource = [
        {
            title:"姓名",
            key:'name'
        },
        {
            title:"年龄",
            key:'age'
        },
        {
            title:"头像地址",
            key:'headimgurl'
        },
        {
            title:"学历",
            key:'degree'
        },
        {
            title:"班级",
            key:'class'
        },
        {
            title:"创建时间",
            key:'cTime'
        }
    ]
    qee(titleSource,tableData.value,'CRM系统学员信息表')
}

</script>


<script>
export default{
    meta:{
        title: 'xyxmgl', 
         name: '学员项目管理',
         routeName:"stuProduct",
         icon:'#icon-shangpinguanli'
    }
}


</script>


<style lang="less" scoped>
.input{
    display: flex;
    justify-content: flex-start;
    align-content: center;
    margin-bottom: 20px;
    .el-select{
        width: 300px;
        height: 40px;
        margin-right: 10px;

        :deep(.el-input__inner){
            height: 40px;
        }
    }

    .el-button{
        height: 42px;
        width: 100px;

        .el-icon{
            font-size: 20px;
        }
    }
}

.export{
    display: flex;
    justify-content: flex-end;
    :deep(.el-button){
        display: flex;
        justify-content: flex-end;
        align-content: center;
    }
}

.table{
    :deep(.el-table__row){
        height: 100px;
    }

    .el-button{
        width: 60px;
    }
    .el-icon{
        margin-right: 6px;
    }

}


</style>


